<?php

namespace App\Http\Controllers;

use App\Imports\StaffImport;
use App\Models\Building;
use App\Models\Department;
use App\Models\Dorm;
use App\Models\DormType;
use App\Models\StaffDormAdjust;
use App\Models\StaffPosition;
use App\Presenters\StaffPresenter;
use Carbon\Carbon;
use http\Env\Response;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Prettus\Validator\Exceptions\ValidatorException;
use App\Http\Requests\StaffCreateRequest;
use App\Http\Requests\StaffUpdateRequest;
use App\Repositories\StaffRepository;

/**
 * Class StaffController.
 *
 * @package namespace App\Http\Controllers;
 */
class StaffController extends Controller
{
    /**
     * @var StaffRepository
     */
    protected $repository;

    /**
     * StaffController constructor.
     *
     * @param StaffRepository $repository
     * @param StaffValidator $validator
     */
    public function __construct(StaffRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {

        $this->repository->pushCriteria(app('Prettus\Repository\Criteria\RequestCriteria'));
        $this->repository->setPresenter(StaffPresenter::class);
        if (request()->has('export')) {
            set_time_limit(0);
            $staffs = $this->repository->withCount('families')->all();
        } else {
            $staffs = $this->repository->withCount('families')->paginate(\request()->get('limit'));
            request()->flash();
        }

        if (request()->wantsJson()) {
            return response()->json([
                'data' => $staffs,
            ]);
        }
        $departments = Department::all(['id', 'name']);
        $staffPositions = StaffPosition::all(['id', 'position']);
        $buildings = Building::all(['id', 'name']);
        return view('staff.index', compact('staffs', 'departments', 'staffPositions', 'buildings'));
    }

    public function create()
    {
        $departments = Department::all()->pluck('name', 'id');
//        $staffs = Staff::orderBy('name')->get(['id','name','sex','id_card']);
        $staffPositions = StaffPosition::all()->pluck('position', 'id');
        return view('staff.create', compact('departments', 'staffPositions'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  StaffCreateRequest $request
     *
     * @return \Illuminate\Http\Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function store(StaffCreateRequest $request)
    {
        try {
            $id_card = $request->get('id_card');
            $card_num = $request->get('card_num');
            if ($id_card) {
                $sameIds = $this->repository->findWhere(['id_card' => $id_card])->count();
                if ($sameIds) {
                    return response()->json([
                        'error' => true,
                        'message' => '身份证不允许重复'
                    ]);
                }

            }

            if ($card_num) {
                $sameNums = $this->repository->findWhere(['card_num' => $card_num])->count();
                if ($sameNums) {
                    return response()->json([
                        'error' => true,
                        'message' => '工号不允许重复'
                    ]);
                }

            }

            $staff = $this->repository->create($request->all());

            $response = [
                'message' => 'Staff created.',
                'data' => $staff->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {
            if ($request->wantsJson()) {
                return response()->json([
                    'error' => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $staff = $this->repository->find($id);

        if (request()->wantsJson()) {

            return response()->json([
                'data' => $staff,
            ]);
        }

        return view('staff.show', compact('staff'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $staff = $this->repository->find($id);
        $departments = Department::all()->pluck('name', 'id');
//        $staffs = Staff::orderBy('name')->get(['id','name','sex','id_card']);
        $staffPositions = StaffPosition::all()->pluck('position', 'id');
        return view('staff.edit', compact('staff', 'departments', 'staffPositions'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  StaffUpdateRequest $request
     * @param  string $id
     *
     * @return Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function update(StaffUpdateRequest $request, $id)
    {
        try {
            \DB::beginTransaction();
            $staff = $this->repository->update($request->all(), $id);

            if ($request->get('status') < 1 && $staff->dorm_id) {
                //离职时同时新增一条搬出宿舍的记录
                $adjust_date = $request->get('leave_date') ? $request->get('leave_date') : Carbon::now()->format('Y-m-d');
                if ($staff->dorm_id) {
                    $adjust = new StaffDormAdjust();
                    $adjust->staff_id = $staff->id;
                    $adjust->dorm_id_from = $staff->dorm_id;
                    $adjust->adjust_date = $adjust_date;
                    $adjust->save();
                }
                $staff->dorm_id = null;
                $staff->latest_in_date = null;
                $staff->save();
            }
            $response = [
                'message' => 'Staff updated.',
                'data' => $staff->toArray(),
            ];
            \DB::commit();
            if ($request->wantsJson()) {
                return response()->json($response);
            }
            return redirect()->back()->with('message', $response['message']);
        } catch (\Exception $e) {
            \DB::rollBack();
            if ($request->wantsJson()) {
                return response()->json([
                    'error' => true,
                    'message' => $e->getMessage()
                ]);
            }
            return redirect()->back()->withErrors($e->getMessage())->withInput();
        }
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $count = StaffDormAdjust::where('staff_id', $id)->count();
        if ($count) {
            return response()->json([
                'error' => true,
                'message' => '不能有删除有宿管记录的人员'
            ]);
        }

        $deleted = $this->repository->delete($id);

        if (request()->wantsJson()) {

            return response()->json([
                'message' => 'Staff deleted.',
                'deleted' => $deleted,
            ]);
        }

        return redirect()->back()->with('message', 'Staff deleted.');
    }

    public function dormArrange($id)
    {
        $staff = $this->repository->with('dorm')->find($id);
        if (request()->get('check_dorm_type')) {
            $dorms = Dorm::availableDorms($staff)->get();
        } else {
            $dorms = Dorm::with('building:id,name', 'dormType:id,name', 'staffs')->withCount('staffs')->get();
        }

        if (\request()->get('include_take_over')) {
            $dorms = $dorms->filter(function ($v) {
                return $v->staffs_count > -1;
            });
        } else {
            $dorms = $dorms->filter(function ($v) {
                return $v->staffs_count < $v->beds;
            });
        }
        if (request()->get('dorm_type_id')) {
            $dorms = $dorms->filter(function ($v) {
                return $v->dorm_type_id == request()->get('dorm_type_id');
            });
        }
        if (request()->get('building_id')) {
            $dorms = $dorms->filter(function ($v) {
                return $v->building_id == request()->get('building_id');
            });
        }

        $dorms = $dorms->values()->all();
        $data = new class
        {
        };
        $data->msg = "";
        $data->code = 0;
        $data->count = count($dorms);
        $data->data = $dorms;

        //筛选表异步请求所需的宿舍数据
        if (\request()->wantsJson()) {
            return response()->json($data);
        }
        $dormTypes = DormType::all()->pluck('name', 'id');
        $buildings = Building::all()->pluck('name', 'id');
        return view('staff.dorm-arrange', compact('staff', 'dormTypes', 'buildings'));
    }

    public function handleExcelImport(Request $request)
    {
        $file = $request->file('file');
        //判断文件是否上传成功
        if ($file->isValid()) {
            try {
                $import = new StaffImport();
                Excel::import($import, $request->file('file'));
                return \response()->json(['code' => 0, 'msg' => "共 $import->total 条，成功 $import->success 条，失败 $import->fail 条，忽略 $import->ignore 条"]);
            } catch (\Exception $exception) {
                return \response()->json(['code' => -1, 'msg' => 'fail:' . $exception->getMessage()]);
            }

        } else {
            return \response()->json(['code' => -1, 'msg' => 'file not valid, import fail']);
        }
    }

    public function handleTemplateDownload()
    {
        return response()
            ->download(realpath(base_path('public/template')) . '/staff_info.xlsx', '员工导入模板.xlsx');

    }

}
